﻿using System;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;

using SBPweb.PROvibe.Client.Framework.Contracts.Content;
using SBPweb.PROvibe.Client.Framework.Utilities.Collections;

namespace SBPweb.PROvibe.Client.Framework.Content
{

    public abstract class ThemeManagerBase : OverridableDictionary<string, ResourceDictionary>, IThemeManager
    {

        #region Private fields

        private IContentManager contentManager;
        private string currentThemeName;

        #endregion

        #region Constructor logic

        public ThemeManagerBase(IContentManager contentManager)
        {
            this.contentManager = contentManager;
        }

        #endregion

        #region Property accessors

        public IContentManager ContentManager
        {
            get
            {
                return contentManager;
            }
        }

        public string CurrentThemeName
        {
            get
            {
                return currentThemeName;
            }
            set
            {
                SetTheme(value);
            }
        }

        #endregion

        #region Events

        public event EventHandler Initializing;

        public event EventHandler Initialized;

        #endregion

        #region Methods

        public void Initialize()
        {
            if (Initializing != null)
            {
                Initializing(this, EventArgs.Empty);
            }
            base.BeginInitialization();
            this.InitializeThemes();
            base.EndInitialization();
            if (this.Count > 0)
            {
                IEnumerator<KeyValuePair<string, ResourceDictionary>> enu = this.GetEnumerator();
                enu.MoveNext();
                CurrentThemeName = enu.Current.Key;
            }
            if (Initialized != null)
            {
                Initialized(this, EventArgs.Empty);
            }
        }

        protected void Add(ResourceDictionary theme)
        {
            ITheme itheme = theme as ITheme;
            if (itheme == null)
            {
                throw new ArgumentException("Parameter provided is not an ITheme instance...");
            }
            base.Add(itheme.Name, theme);
        }

        protected abstract void InitializeThemes();

        private void SetTheme(string themeName)
        {
            string oldThemeName = currentThemeName;

            if (string.IsNullOrEmpty(oldThemeName))
            {
                Copy(this[themeName], Application.Current.Resources);
            }
            else
            {
                Copy(this[themeName], Application.Current.Resources, this[oldThemeName]);
            }
            currentThemeName = themeName;
        }

        private void Copy(ResourceDictionary source, ResourceDictionary destination)
        {
            Copy(source, destination, null);
        }

        private void Copy(ResourceDictionary source, ResourceDictionary destination, ResourceDictionary backup)
        {
            IEnumerable enm = source as IEnumerable;
            try
            {
                IEnumerator ena = enm.GetEnumerator();
            }
            catch
            {
                enm = destination as IEnumerable;
            }
            foreach (string key in enm)
            {
                DependencyObject value = source[key] as DependencyObject;
                if (destination.Contains(key))
                {
                    DependencyObject prevValue = destination[key] as DependencyObject;
                    destination.Remove(key);
                    if (backup != null)
                    {
                        backup.Add(key, prevValue);
                    }
                }
                source.Remove(key);
                destination.Add(key, value);
            }
        }

        #endregion

        #region Helper functions

        //public static void BeginElementStoryBoard(FrameworkElement sender, string targetName, string storyBoardName)
        //{
        //    BeginElementStoryBoard(sender, Application.Current.Resources, targetName, storyBoardName);
        //}

        //public static void BeginElementStoryBoard(FrameworkElement sender, ResourceDictionary resources, string targetName, string storyBoardName)
        //{
        //    if (!resources.Contains(storyBoardName))
        //    {
        //        throw new ArgumentException(string.Format("Resource with name {0} not found!", storyBoardName));
        //    }
        //    Storyboard sbAlpha = resources[storyBoardName] as Storyboard;
            
        //    UIElement target = sender.FindName(targetName) as UIElement;
        //    Storyboard sb = ThemeManagerBase.CloneStoryBoard(sbAlpha);
        //    Storyboard.SetTarget(sb, target);
        //    Storyboard.SetTargetProperty(sb, new PropertyPath("Opacity"));
        //    sb.Begin();
        //}

        //public void BeginElementStoryBoard(UIElement target, ResourceDictionary resources, string storyBoardName, PropertyPath propertyPath)
        //{
        //    if (!resources.Contains(storyBoardName))
        //    {
        //        throw new ArgumentException(string.Format("Resource with name {0} not found!", storyBoardName));
        //    }
        //    Storyboard sbAlpha = resources[storyBoardName] as Storyboard;

        //    Storyboard sb = ThemeManagerBase.CloneStoryBoard(sbAlpha);
        //    Storyboard.SetTarget(sb, target);
        //    Storyboard.SetTargetProperty(sb, propertyPath);
        //    sb.Begin();
        //}

        #endregion

    }

}